package com.btb.adapter.contract;

import java.math.BigInteger;
import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.Uint;
import org.web3j.abi.datatypes.Utf8String;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.protocol.core.DefaultBlockParameter;
import org.web3j.protocol.core.methods.response.TransactionReceipt;

import com.btb.adapter.utils.Fmt;
import com.btb.adapter.vo.HeroDetail;
import com.btb.adapter.vo.OffChainEventEventResponse;
import com.btb.adapter.vo.UpChainEventEventResponse;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ActHeroService {
	@Autowired
	private ActHero actHero;

	public TransactionReceipt upChain(String _address, BigInteger _tokenId, BigInteger _heroArea, BigInteger _grade,
			BigInteger _season, BigInteger _powerValue, BigInteger _productionDate, String _name, String _cardTips,
			String _cardImage) {
		try {
			return actHero.upChain(_address, _tokenId, _heroArea, _grade, _season, _powerValue, _productionDate, _name, _cardTips, _cardImage).send();
		} catch (Exception e) {
			log.error("hero upChain err:{}", e.getMessage(), e);
		}
		return null;
	}

	public TransactionReceipt offChain(String _address, List<BigInteger> _tokenIds, BigInteger _clientid) {
		try {
			return  actHero.offChain(_address, _tokenIds, _clientid).send();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public HeroDetail heroDetail(BigInteger tokenId) {
		List<Type> results = actHero.heroDetail(tokenId);
		if(Objects.isNull(results)) {
			return null;
		}
		Uint heroArea = (Uint) results.get(0);
		Uint grade = (Uint) results.get(1);
		Uint season = (Uint) results.get(2);
		Uint powerValue = (Uint) results.get(3);
		Uint productionDate = (Uint) results.get(4);
		Utf8String name = (Utf8String) results.get(5);
		Utf8String cardTips = (Utf8String) results.get(6);
		Utf8String cardImage = (Utf8String) results.get(7);
		// 如果没有上链,  依然是有结果返回的, 都是默认值
		if(Objects.equals(heroArea, new Uint(new BigInteger("0")))
				&& Objects.equals(grade, new Uint(new BigInteger("0")))
				&& Objects.equals(season, new Uint(new BigInteger("0")))
				&& Objects.equals(powerValue, new Uint(new BigInteger("0")))
				&& Objects.equals(productionDate, new Uint(new BigInteger("0")))
				&& Objects.equals(name, new Utf8String(StringUtils.EMPTY))
				&& Objects.equals(cardTips, new Utf8String(StringUtils.EMPTY))
				&& Objects.equals(cardImage, new Utf8String(StringUtils.EMPTY))
				) {
			return null;
		}
		return HeroDetail.builder()
				.tokenId(tokenId.longValue())
				.heroArea(Fmt.btoi(heroArea))
				.grade(Fmt.btoi(grade))
				.season(Fmt.btoi(season))
				.powerValue(Fmt.btol(powerValue))
				.productionDate(Fmt.btol(productionDate))
				.name(Fmt.utf8tos(name))
				.cardTips(Fmt.utf8tos(cardTips))
				.cardImage(Fmt.utf8tos(cardImage))
				.build();
	}

	public List<UpChainEventEventResponse> upChainEvent(String startBlockNumber, String endBlockNumber) {
		return actHero.upChainEventEventFlowableEx(DefaultBlockParameter.valueOf(new BigInteger(startBlockNumber)),
				DefaultBlockParameter.valueOf(new BigInteger(endBlockNumber)));
	}

	public List<OffChainEventEventResponse> offChainEvent(String startBlockNumber, String endBlockNumber) {
		return actHero.offChainEventEventFlowableEx(DefaultBlockParameter.valueOf(new BigInteger(startBlockNumber)),
				DefaultBlockParameter.valueOf(new BigInteger(endBlockNumber)));
	}
}
